#include <iostream>
#include<cstring>
#include <winsock2.h>
#include<sstream>

using namespace std;

typedef struct Date {
    float m1;
    float m2;
    float m3;
    float m_roll;
    float m_pitch;
    float m_rotate;
} Datablock;

#define PARALLEL (2)          // 轮询
#define DEBUG_NET_DELAY (10)   // 网络延迟DEBUG_NET_DELAY ms

LARGE_INTEGER t1[PARALLEL], t2[PARALLEL], td;

void setNetDelay(int index) {
    do {
        QueryPerformanceCounter(&t2[index]);
    } while ((t2[index].QuadPart - t1[index].QuadPart) < td.QuadPart);
}

int ReceiveData(SOCKET conn, char *recvData, int sendBytes, int flags) {
    int recvBytes = 0;

    while (recvBytes != sendBytes) {
        int ret = recv(conn, recvData + recvBytes, sendBytes - recvBytes, flags);   // 循环接收网络数据
        if (ret > 0)
            recvBytes = recvBytes + ret;
    };

    return recvBytes;
}

int SendData(SOCKET s, const char *buf, int len, int flags) {
    //sendmutex_decoder.lock();
    int ret = 0;
    if (len)
        ret = send(s, buf, len, flags);
    //printf("Send: \tSocket = %d, \tret = %d, \tError = %d, \tsendlen = %d\n", s, ret, GetLastError(), len);
    //sendmutex_decoder.unlock();
    return ret;
}

int main() {
    LARGE_INTEGER tc;
    QueryPerformanceFrequency(&tc);
    td.QuadPart = (LONGLONG) (tc.QuadPart / 1000.0 * DEBUG_NET_DELAY);

    cout << "client start" << endl;
    //初始化winsock   
    WSADATA wsaD;
    WSAStartup(MAKEWORD(1, 1), &wsaD);
    //创建客户端socket   
    SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    //连接服务器   
    u_long iMode = 1;//如果设置为0，为阻塞式的
    ioctlsocket(sclient, FIONBIO, &iMode);
    struct sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;

    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //指定服务器
    servaddr.sin_port = htons(8088);             //指定端口   
    cout << endl << "OK" << endl;

    connect(sclient, (struct sockaddr *) &servaddr, sizeof(servaddr)); //通过套接字连接主机

    Datablock recv_data, send_data = {0, 0, 0, 0, 0, 0};
//    while (true) {
//        int len = send(sclient, (char *)&send_data, sizeof(Datablock), 0);
//        //存储接收的字符
//        len = recv(sclient, (char *)&recv_data, sizeof(Datablock), 0);  //通过连接套接字接收数据
//        if (len > 0)
//        {
//            cout << recv_data.m1 << endl;
//            cout << recv_data.m2 << endl;
//            cout << recv_data.m3 << endl;
//            cout << recv_data.m_roll << endl;
//            cout << recv_data.m_pitch << endl;
//            cout << recv_data.m_rotate << endl;
//        }
//    }

    LARGE_INTEGER start, end;
    QueryPerformanceCounter(&start);

    int len[PARALLEL] = {0};
    for (int i = 0; i < PARALLEL; i++) {   // 未结束纠错
        for (int index = 0; index < PARALLEL; index++) {
#if DEBUG_NET_DELAY != 0
            if (len[index])   // 发送过数据
                setNetDelay(index);
#endif
            // 接收并比较校验子
            int l = ReceiveData(sclient, (char *) &recv_data, len[index], 0);  //通过连接套接字接收数据

            if (l > 0) {
                cout << recv_data.m1 << endl;
                cout << recv_data.m2 << endl;
                cout << recv_data.m3 << endl;
                cout << recv_data.m_roll << endl;
                cout << recv_data.m_pitch << endl;
                cout << recv_data.m_rotate << endl << endl;
            }

            for (int j = 0; j < 100000; j++){
                j++;
                j--;
            }
            // 网络发送
            send_data.m1 = i;
            send_data.m2 = index;
            SendData(sclient, (char *) &send_data, sizeof(Datablock), 0);
            len[index] = sizeof(Datablock);
            QueryPerformanceCounter(&t1[index]);
        }
    }

    QueryPerformanceCounter(&end);
    printf("network time: %lld - %lld = %lld(%fms)\n", end.QuadPart, start.QuadPart, end.QuadPart - start.QuadPart,
           (double) (end.QuadPart - start.QuadPart) / tc.QuadPart * 1000);
    return 0;
}